﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace ProgNetComponents.Validation.Rules
{
    /// <summary>
    /// Validation rule for string values
    /// </summary>
    public class ColumnStringValueValidationRule : ColumnValidationRule
    {
        /// <summary>
        /// Initializes the <see cref="ColumnStringValueValidationRule"/> class.
        /// </summary>
        static ColumnStringValueValidationRule()
        {
            ErrorEquals = "Ta wartość powinna byc równa \"{0}\".";
            ErrorDoesNotEqual = "Ta wartość powinna byc różna od \"{0}\".";
            ErrorContains = "Ta wartość powinna zawierać \"{0}\".";
            ErrorDoesNotContain = "Ta wartość nie powinna zawierać \"{0}\".";
            ErrorStartsWith = "Ta wartość powinna zaczynać się od \"{0}\".";
            ErrorDowsNotStartWith = "Ta wartość nie powinna zaczynać się od \"{0}\".";
            ErrorEndsWith = "Ta wartość powinna kończyć się na \"{0}\".";
            ErrorDoesNotEndWith = "Ta wartość nie powinna kończyć się na \"{0}\".";
        }

        /// <summary>
        /// Gets or sets the error equals.
        /// </summary>
        /// <value>
        /// The error equals.
        /// </value>
        public static string ErrorEquals{get;set;}
        /// <summary>
        /// Gets or sets the error does not equal.
        /// </summary>
        /// <value>
        /// The error does not equal.
        /// </value>
        public static string ErrorDoesNotEqual{get;set;}
        /// <summary>
        /// Gets or sets the error contains.
        /// </summary>
        /// <value>
        /// The error contains.
        /// </value>
        public static string ErrorContains{get;set;}
        /// <summary>
        /// Gets or sets the error does not contain.
        /// </summary>
        /// <value>
        /// The error does not contain.
        /// </value>
        public static string ErrorDoesNotContain{get;set;}
        /// <summary>
        /// Gets or sets the error starts with.
        /// </summary>
        /// <value>
        /// The error starts with.
        /// </value>
        public static string ErrorStartsWith{get;set;}
        /// <summary>
        /// Gets or sets the error dows not start with.
        /// </summary>
        /// <value>
        /// The error dows not start with.
        /// </value>
        public static string ErrorDowsNotStartWith{get;set;}
        /// <summary>
        /// Gets or sets the error ends with.
        /// </summary>
        /// <value>
        /// The error ends with.
        /// </value>
        public static string ErrorEndsWith{get;set;}
        /// <summary>
        /// Gets or sets the error does not end with.
        /// </summary>
        /// <value>
        /// The error does not end with.
        /// </value>
        public static string ErrorDoesNotEndWith { get; set; }

        /// <summary>
        /// Gets or sets the comparsion.
        /// </summary>
        /// <value>
        /// The comparsion.
        /// </value>
        [RefreshProperties(System.ComponentModel.RefreshProperties.All)]
        public StringComparsion Comparsion
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets a value indicating whether [case sensitive].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [case sensitive]; otherwise, <c>false</c>.
        /// </value>
        [DefaultValue(false)]
        public bool CaseSensitive { get; set; }

        /// <summary>
        /// Gets the default error string.
        /// </summary>
        /// <value>
        /// The default error string.
        /// </value>
        protected override string DefaultErrorString
        {
            get
            {
                switch (Comparsion)
                {
                    case StringComparsion.Equals:
                        return ErrorEquals;
                    case StringComparsion.DoesNotEqual:
                        return ErrorDoesNotEqual;
                    case StringComparsion.Contains:
                        return ErrorContains;
                    case StringComparsion.DoesNotContain:
                        return ErrorDoesNotContain;
                    case StringComparsion.StartsWith:
                        return ErrorStartsWith; 
                    case StringComparsion.DowsNotStartWith:
                        return ErrorDowsNotStartWith;
                    case StringComparsion.EndsWith:
                        return ErrorEndsWith;
                    case StringComparsion.DoesNotEndWith:
                        return ErrorDoesNotEndWith;
                    default:
                        return null;
                }
            }
        }

        /// <summary>
        /// Gets formatted error string
        /// </summary>
        /// <value>
        /// The formated error string.
        /// </value>
        public override string FormatedErrorString
        {
            get
            {
                return ErrorString.XFormat(Value);
            }
        }

        /// <summary>
        /// Gets or sets the value.
        /// </summary>
        /// <value>
        /// The value.
        /// </value>
        public string Value { get; set; }

        /// <summary>
        /// Does the validate.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <returns></returns>
        protected override bool DoValidate(System.Data.DataRow row)
        {
            string val1 = row[Column].AsString();
            string val2 = Value.AsString();
            if (!CaseSensitive)
            {
                val1 = val1.ToUpper();
                val2 = val2.ToUpper();
            }
            switch (Comparsion)
            {
                case StringComparsion.Equals:
                    return val1 == val2;
                case StringComparsion.DoesNotEqual:
                    return val1 != val2;
                case StringComparsion.Contains:
                    return val1.Contains(val2);
                case StringComparsion.DoesNotContain:
                    return !val1.Contains(val2);
                case StringComparsion.StartsWith:
                    return val1.StartsWith(val2);
                case StringComparsion.DowsNotStartWith:
                    return !val1.StartsWith(val2);
                case StringComparsion.EndsWith:
                    return val1.EndsWith(val2);
                case StringComparsion.DoesNotEndWith:
                    return !val1.EndsWith(val2);
                default:
                    break;
            }
            return true;
        }
    }
}
